<template>
  <Dialog v-model="dialogVisible" :title="dialogTitle" width="800px">
    <div class="map-head">
      <el-select
        v-model="addrVal"
        clearable
        remote
        filterable
        reserve-keyword
        placeholder="请输入关键词"
        style="width: 320px"
        :remote-method="remoteMethod"
        @change="selectChange"
      >
        <el-option
          v-for="item in addrList"
          :key="item.id"
          :label="item.name"
          :value="item.name + '_' + item.district"
        >
          <div class="option" style="display: flex; justify-content: space-between">
            <span>{{ item.name }}</span>
            <span style="margin-left: 20px; color: #999; font-size: 12px">
              {{ item.district }}
            </span>
          </div>
        </el-option>
      </el-select>
      <div class="currentAddr">当前选择地址：{{ currentAddr.name }}</div>
    </div>
    <div id="container" ref="container"></div>
    <template #footer>
      <el-button type="primary" :disabled="formLoading" @click="submitForm">确 定</el-button>
      <el-button @click="dialogVisible = false">取 消</el-button>
    </template>
  </Dialog>
</template>
<script setup name="MapSelectAddress" lang="ts">
import AMapLoader from '@amap/amap-jsapi-loader'
import axios from 'axios'
export interface MapConfigureInter {
  on: Fn
  destroy?: Fn
  clearEvents?: Fn
  addControl?: Fn
  setCenter?: Fn
  getCenter?: Fn
  setZoom?: Fn
  plugin?: Fn
  clearInfoWindow?: Fn
  remove?: Fn
  add?: Fn
}

interface searchTip {
  id: string
  name: string
  district: string
  location: {
    lat: number
    lag: number
  }
}

const emit = defineEmits(['selectValue'])

const formLoading = ref(false)
const message = useMessage()
const dialogTitle = ref('')
const dialogVisible = ref(false)
const container = ref()
const addrVal = ref('')
const currentAddr = ref({
  name: '',
  lng: 114.512598,
  lat: 37.287832
})
const marker = ref()
const addrList = ref<searchTip[]>([])
let map: MapConfigureInter
let AMap

const autoComplete = ref()
const MapConfigure = {
  amapKey: import.meta.env.VITE_AMAP_KEY,
  options: {
    resizeEnable: true,
    center: [currentAddr.value.lng, currentAddr.value.lat],
    zoom: 14 // 初始化地图级别
  }
}
const { options } = MapConfigure

const open = async (address) => {
  if (address.name != '' && address.lng != '' && address.lat != '') {
    currentAddr.value.name = address.name
    currentAddr.value.lng = address.lng
    currentAddr.value.lat = address.lat
  } else {
    currentAddr.value = {
      name: '',
      lng: 114.512598,
      lat: 37.287832
    }
  }
  dialogVisible.value = true
  initMap()
}
defineExpose({ open }) // 提供 open 方法，用于打开弹窗

const initMap = async () => {
  window._AMapSecurityConfig = {
    securityJsCode: import.meta.env.VITE_AMAP_SECURITY_KEY
  }
  AMap = await AMapLoader.load({
    key: MapConfigure.amapKey,
    version: '2.0',
    plugins: ['AMap.AutoComplete', 'AMap.Marker', 'AMap.PlaceSearch', 'AMap.Geolocation']
  })
  // 创建地图实例
  map = new AMap.Map(container.value, options)

  autoComplete.value = new AMap.AutoComplete({})
  addmark(currentAddr.value)
  map.on('click', (e) => {
    getAddress(e.lnglat.getLng(), e.lnglat.getLat())
  })
}

// 地址逆解析
const getAddress = async (lng, lat) => {
  const res = await axios.get(
    `https://restapi.amap.com/v3/geocode/regeo?location=${lng},${lat}&key=e7237d40dc6259a235b25c29d2729949&radius=1000&extensions=all`
  )

  if (res.data.status == 1) {
    addmark({ lng, lat, name: res.data.regeocode.formatted_address })
  } else {
    message.error(res.data.status)
  }
}
const addmark = (info) => {
  if (info.name == '') return
  if (marker.value) map.remove!(marker.value)
  currentAddr.value = info
  marker.value = new AMap.Marker({
    position: new AMap.LngLat(info.lng, info.lat),
    title: info.name, // 鼠标滑过点标记时的文字提示
    label: {
      content: info.name // 文本标注的内容
    }
    // zooms: 14 // 点标记显示的层级范围，超过范围不显示。默认值：zooms: [2, 20]
  })
  map.add!(marker.value)
  map.setCenter!([info.lng, info.lat], false, 500) // 中心点 是否直接迁移(动画过度) 过渡时间
}
// // 自定义远程搜索方法
const remoteMethod = (e) => {
  if (e.trim() != '') {
    setTimeout(() => {
      autoComplete.value.search(e, (status, result) => {
        if (status == 'complete' && result.tips.length) {
          addrList.value = result.tips.filter((v) => v.id != '')
        }
      })
    }, 200)
  }
}
const selectChange = (e) => {
  if (!e) return
  let info = addrList.value.find((v) => v.name + '_' + v.district == e)
  if (info && info.location) {
    addmark({ ...info.location, name: info.name })
  } else {
    message.warning('该地点经纬度信息缺失')
  }
}

const submitForm = () => {
  emit('selectValue', currentAddr.value)
  close()
}

/** 关闭弹窗 */
const close = async () => {
  dialogVisible.value = false
}
</script>
<style lang="scss" scoped>
.map-head {
  height: 40px;
  width: 100%;
  display: flex;
  align-items: center;
  .currentAddr {
    margin-left: 32px;
  }
}

#container {
  height: 500px;
  width: 100%;
  margin-top: 10px;
}
</style>
